<template>
  <div class="vir-dom" @scroll="scroll">
     
    <!-- 虚拟滚动容器 -->
    <div class="pan" :style="{height: cofing.totalHeight + 'px'}"></div>
    <!-- 虚拟滚动内容 -->
    <div class="content" :style="{transform: `translateY(${scrollTopRef}px)`}">
      <!-- 渲染的数据 -->
      <div v-for="item in reanderData" :key="item.id" class="item" :style="{height: itemHeight + 'px',borderBottom: '1px solid #ccc',textAlign: 'center',lineHeight: itemHeight + 'px'}">
        {{ item.id }}
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive ,ref} from "vue";

// 获取屏幕高度
const clineHtight = document.documentElement.clientHeight;
// 每个item的高度
const itemHeight = 60 
// 屏幕内能显示的item数量
const clienItemcount = Math.ceil(clineHtight / itemHeight)
console.log(clienItemcount,'屏幕内能显示的item数量');

// 模拟数据
const sourceDate = new Array(10000).fill(0).map((_,i)=>{
  return {id: i + 1}
})
// 配置项
const cofing = reactive({
  startIndex:0,
  enIndex:0,
  totalHeight:0,
})
// 计算渲染的数据
const reanderData = computed(()=>{
  console.log(sourceDate.slice(cofing.startIndex, cofing.enIndex),'464645');
  return sourceDate.slice(cofing.startIndex, cofing.enIndex)
  
  
})

// 组件挂载时计算总高度
onMounted(()=>{
  //总高度
  cofing.totalHeight = itemHeight * sourceDate.length
  console.log(cofing.totalHeight,'总高度');
  
  cofing.enIndex = clienItemcount + cofing.startIndex
  console.log(cofing.enIndex,'enIndex');
  
})

// 滚动事件
const scroll = (e:any)=>{
  const scrollTop = e.target.scrollTop 
  console.log(scrollTop,'scrollTop');
  cofing.startIndex = Math.floor(scrollTop / itemHeight)
  console.log(cofing.startIndex,'startIndex');
  
  cofing.enIndex = cofing.startIndex + clienItemcount
  console.log(cofing.enIndex,'enIndex1');
  scrollTopRef.value = cofing.startIndex * itemHeight
  console.log(scrollTopRef.value,'scrollTopRef.value');
  
}

//偏移量
const scrollTopRef = ref(0) 

</script>

<style scoped lang="scss">
.vir-dom{
  position: relative; 
  width: 100vw;
  height: 100vh; 
  overflow-y: auto; 
  .content{
    top: 0;
    left: 0;
    position: absolute; 
    width: 100vw;
  }
}
</style>
